var num = 0;
var isExist;

var v4_pingan_debit_java_funcs = {
    openHomePage : function(){
        //打开页面判断代理是否异常
        var html = luaFuncs.get("https://bank.pingan.com.cn/ibp/bank/index.html#home/home/index/1495695054435?returnURL=index%2FindexInfo%2Findex");
        storeDataToFile(context, html, "loginHtml.html")
        context.put("index_html",html);
    },
    //判断代理ip是否异常
    checkProxyAvailable: function(){
        logger.info("任务【{}】，平安借记卡开始进行代理可用性检测",context.get(LUA_TASK_TOKEN));
        var html = context.get("index_html");
        //判断是否代理异常的function
        var isCorrectFunc = function(html){
            return !(html.contains("代理服务器没有响应") || html.contains("无法显示此页"));
        }
        //获取异常信息的方法function
        var getErrorMsgFunc = function(html) {
            return "代理ip异常";
        }
        //返回信息
        return assertTrueOrThrowException(html, isCorrectFunc, getErrorMsgFunc);
    },
    //检测控件是否可用
    checkControlAvailable:function () {
        logger.info("任务【{}】，平安借记卡开始进行控件可用性检测",context.get(LUA_TASK_TOKEN));
        return true;
    },
    checkTargetWebsiteAvailable: function(){
        logger.info("任务【{}】, 平安借记卡开始进行网站可用性检测", context.get(LUA_TASK_KEY));
        return true;
    },
    needRefreshHomePageOrNot : function() {
        return equals(context.get("currentErrorCode"), BALO_99602_40)
    },
    needResetEnvironment:function(){
        return true;
    },

    //登录过程
    login : function () {
        logger.info("任务【{}】，平安借记卡开始进行登录操作",context.get(LUA_TASK_KEY));
        logger.info("---------------------------------LOGIN START-------------------------------------")
        //获取登录参数
        logger.info("任务【{}】,平安借记卡获取登录参数",context.get(LUA_TASK_KEY));
        var userName = getLoginParams(context)[0];
        var password = context.get(Constants.LUA_TASK_TOKEN);
        logger.info("任务【{}】，平安借记卡登录参数获取完成",context.get(LUA_TASK_KEY));

        //调用lua输入用户名，密码
        logger.info("任务【{}】，平安借记卡开始输入登录参数",context.get(LUA_TASK_KEY));
        //打开窗口
        var html = luaFuncs.get("https://bank.pingan.com.cn/ibp/bank/index.html#home/home/index/1495695054435?returnURL=index%2FindexInfo%2Findex");
        Thread.sleep(15000);
        luaFuncs.show();
        //点击密码登录tab
        luaFuncs.click_pwd_login_tab();

        //输入用户名
        var inputUResult = luaFuncs.set_input_text_by_id("userName",userName);
        //点击密码框旁的小键盘
        luaFuncs.click_by_id_wait_id("pwdObject1-btn", "");
        Thread.sleep(100);
        //关闭小键盘
        luaFuncs.click_by_id_wait_id("pa_ui_keyboard_close", "");
        Thread.sleep(100);
        //输入密码
        var inputPResult = luaFuncs.set_input_text_by_id("pwdObject1-input", password);

        Thread.sleep(100);
        logger.info("任务【{}】，平安借记卡账号密码输入结束，输入结果:{}",context.get(LUA_TASK_KEY),inputUResult+"_"+inputPResult);
        //校验用户名密码是否输入成功
        var isInputSucCorrectFunc = function(inputResult){
            return inputResult.equals("ok_ok");
        }
        //获取异常信息的方法function
        var getInputSucErrorMsgFunc = function(inputResult) {
            return "密码因控件输入错误";
        }
        //返回信息
        assertTrueOrThrowException(inputUResult+"_"+inputPResult, isInputSucCorrectFunc, getInputSucErrorMsgFunc);
        //点击登录
        logger.info("任务【{}】,用户名密码输入完成，点击登录按钮开始登录",context.get(LUA_TASK_KEY));
        luaFuncs.click_pingan_wait("login_btn", 10000);
        logger.info("任务【{}】,点击登录按钮完成，开始校验是否需要短信验证码",context.get(LUA_TASK_KEY));
        //判断是否需要短信验证码
        isExist = is_exist_by_id("otp_password");
        var inputMsg = "true";
        luaFuncs.hide();
        if(isExist){
            logger.info("任务【{}】，平安借记卡输入短信验证码", context.get(LUA_TASK_KEY));
            //等待用户输入短信验证码
            var smsCode = waitSmsCodeBySeconds(context,140);
            luaFuncs.show();
            logger.info("任务【{}】,平安借记卡接收到用户输入的短信验证码：{}",context.get(LUA_TASK_KEY),smsCode);
            //输入短信验证码
            luaFuncs.set_input_text_by_id("otp_password", smsCode);
            Thread.sleep(100);
            //点击确定按钮
            luaFuncs.click_by_id_wait_id("loginOtp_submit", "");
            Thread.sleep(3000)
            //判断短信验证码是否正确 18539958027s otp_errorMsg
            var checkSmsCode  = luaFuncs.get_sms_error_by_id();
            storeDataToFile(context,checkSmsCode, "inputSmsResult.txt");
            if(checkSmsCode.contains("动态密码已过期")){
                logger.info("任务【{}】,平安借记卡，动态验证码过期",context.get(LUA_TASK_KEY));
                inputMsg = "短信验证码超时";
            }else if(checkSmsCode.contains("动态密码错误")){
                logger.info("任务【{}】,平安借记卡，动态验证码错误",context.get(LUA_TASK_KEY));
                inputMsg = "短信验证码错误";
            }
        }
        //验证验证码是否正确的流程
        var isSmsSucCorrectFunc = function(inputMsg){
            return inputMsg.equals("true");
        }
        //获取异常信息的方法function
        var getSmsSucErrorMsgFunc = function(inputMsg) {
            return inputMsg;
        }
        //返回信息
        assertTrueOrThrowException(inputMsg, isSmsSucCorrectFunc, getSmsSucErrorMsgFunc);
        logger.info("任务【{}】，平安借记卡短信验证码校验成功,开始校验最终是否登录成功",context.get(LUA_TASK_KEY));
        //判断是否登录成功
        var loginStatus = checkLoginStatus();
        //检测登录是否成功的流程
        var isLoginSucCorrectFunc = function(loginStatus){
            return StringUtils.isNotBlank(loginStatus) && loginStatus.equals("yes");
        }
        //获取异常信息的方法function
        var getLoginSucErrorMsgFunc = function(loginStatus) {
            return loginStatus;
        }
        //返回信息
        logger.info("任务【{}】，平安借记卡登录流程结束，登录结果：{}",context.get(LUA_TASK_KEY),loginStatus);
        assertTrueOrThrowException(loginStatus, isLoginSucCorrectFunc, getLoginSucErrorMsgFunc);
    },
    crawl:function(){
        var dataList = new ArrayList();
        logger.info("平安借记卡抓取开始，taskKey:{}", context.get(LUA_TASK_KEY));
        //保存信息
        saveInfo(dataList);
        context.put("debit_data", dataList);
        logger.info("平安借记卡抓取完成，taskKey:{}", context.get(LUA_TASK_KEY));
    },
    exitLogin:function () {
    },
    releaseResources:function(){}
}

/**
 * 获取卡名
 */
function getCardName(cardName) {
    //获取卡名
    cardName = luaFuncs.get_html_by_id("clientName");
    //重试，防止网络问题
    if(StringUtils.isBlank(cardName) || cardName.contains("return")){
        for (var i = 0; i < 5; i++) {
            Thread.sleep(2000);
            cardName = luaFuncs.get_html_by_id("clientName");
            if(StringUtils.isNotBlank(cardName) && !cardName.contains("return")){
                return cardName;
            }
        }
    }
    return cardName;
}

/**
 * 保存信息
 */
function saveInfo(dataList){
    var cardName = "";
    if(!isExist){//如果没有短信需要在此处获取卡名
        cardName = getCardName(cardName);
    }
    //获取借记卡基本信息
    var url = "https://bank.pingan.com.cn/ibp/ibp4pc/work/account/acctInfoForIndex.do";
    var map = new HashMap();
    map.put("channelType", "d");
    map.put("responseDataType", "JSON");
    var rsp = luaFuncs.ajax_post(url, map);
    storeDataToFile(context,rsp, "1_bankset_1.txt");
    logger.info("平安借记卡基本信息，taskKey:{}", context.get(LUA_TASK_KEY));
    var rspMap = JSON.parse(rsp);
    //表示没有登录成功
    if(rspMap==null){
        logger.info("平安借记卡基本信息存在空值，taskKey:{}", context.get(LUA_TASK_KEY));
        throw new BankException(BACR_21301_10, "登录成功后请求未成功获取到基本数据");
    }
    var body = rspMap.get("responseBody");
    if(body==null){
        logger.info("平安借记卡基本信息存在空值，taskKey:{}", context.get(LUA_TASK_KEY));
        throw new BankException(BACR_21301_10, "登录成功后请求未成功获取到基本数据");
    }
    var cardList = body.get("cardList");
    var balanceList = body.get("cardBalanceList");
    for (var i = 0; i < cardList.size(); i++) {
        num = i+1;

        var cardMap = cardList.get(i);
        var data = new CreditCardAllData();

        var dec = new BigDecimal("0");
        var accNum = cardMap.get("accNum");

        if(isExist){//如果有短信需要在此处获取卡名
            cardName = getCardName(cardName);
        }
        storeDataToFile(context,rsp, num+"_baseinfo_1.txt");
        if(cardName==null){
            cardName = "";
        }else{
            var names = cardName.split("，");
            cardName = names.length == 2 ? names[1] : "";
        }

        data.setNameOnCard(cardName);//持卡人姓名
        //卡编号
        data.setCardId(UUID.randomUUID().toString());
        //银行
        data.setBankName("平安银行");
        //卡类型
        data.setCardType("借记卡");
        //卡号
        data.setFullCardNum(accNum);
        //信用额度
        data.setCreditLimit(null);
        //可用取现额度
        data.setCashBalance(null);
        //现金额度
        data.setCashLimit(null);
        //开卡时间
        data.setOpenTime(yyyy_MM_dd_PARSER.parse((cardMap.get("openAccDate")).split(" ")[0]));
        //卡号后四位
        data.setCardNum(accNum.substring(accNum.length()-4));
        //开户银行
        data.setOpenBank(cardMap.get("openAccBank"));
        //计算借记卡余额
        for each(var balanceMap in balanceList) {
            var balanceAccNum = balanceMap.get("accNum");
            if(balanceAccNum !=null && balanceAccNum.equals(data.getFullCardNum())){

                var balance = balanceMap.get("balance");
                if(balance!=null){
                    var d = new BigDecimal(balance);
                    if(balance.matches("^\\d+\\.(\\d{3,})$")){
                        d = d.setScale(2, RoundingMode.HALF_UP);
                    }
                    data.setBalance(d);
                }
            }
        }
        //账单列表
        setDataBills(data);
        //存款信息
        setDataDeposits(data);

        dataList.add(data);
    }
}

/**
 * 设置deposits信息，存款信息
 */
function setDataDeposits(data){
    var depositList = new ArrayList();
    var deposit = new CreditCardTimeDeposit();
    //存款余额
    deposit.setBalance(data.getBalance());
    //币种
    deposit.setCurrencyType("CNY");
    //存款类型
    deposit.setDepositType("活期储蓄");
    //存期
    deposit.setPeriod(null);
    //利息
    deposit.setInterest(null);

    depositList.add(deposit);
    data.setDeposits(depositList);
}

/**
 * 设置bills信息，消费信息
 */
function setDataBills(data){
    var billList = new ArrayList();

    var cardNum = data.getFullCardNum();
    var map = new HashMap();
    map.put("accNo", cardNum);
    map.put("accNumSelected", cardNum);
    map.put("bankType", "0");
    map.put("channelType", "d");
    map.put("currType", "RMB");
    map.put("pageIndex", "1");
    map.put("queryAccType", "1");
    map.put("responseDataType", "JSON");

    //消费信息只获取最新6个月
    var cal = Calendar.getInstance();
    var openTime = data.getOpenTime();
    var year = 0, month = 0;
    //判断开户时间是否为空
    if(!StringUtils.isBlank(yyyy_MM_dd_FORMAT.format(openTime))){
        var times = yyyy_MM_dd_FORMAT.format(openTime).split("-");
        if(times.length==3){
            year = times[0];
            month = times[1];
        }
    }
    var count = 0;
    while(true){
        if(count==36){
            break;
        }
        var isDecr = true;
        if(count==0){
            isDecr = false;
        }
        count++;

        //获取月份的月初和月末
        var startEnd = getStartEnd(cal, isDecr);
        //月初
        var time = startEnd.get("startDate");

        if(year!=0 && month!=0){
            //当年
            var nowYear = time.substring(0, 4);
            //当前月份
            var nowMonth = time.substring(4, 6);
            if(nowYear>year || (nowYear==year && nowMonth>=month)){
                //201608 201609
            }else{
                break;
            }
        }

        map.putAll(startEnd);
        //获取借记卡信息
        var rsp = luaFuncs.ajax_post("https://bank.pingan.com.cn/ibp/ibp4pc/work/pcqryTransList.do", map);
        storeDataToFile(context, rsp,  num+"_bill_shopping_sheets_"+count+".txt")
        logger.info("平安借记卡获取36个月信息，taskKey:{}, 第{}个月份:{}", context.get(LUA_TASK_KEY), count, time);

        var rspMap = JSON.parse(rsp);
        var responseBody = rspMap.get("responseBody");
        var transList =  responseBody.get("transList");

        var bill = new BillAllData();
        bill.setInstallments(new ArrayList());
        //账单编号
        bill.setBillId(data.getCardId());
        //账单类型
        bill.setBillType("");
        //银行
        bill.setBankName("平安银行");
        //初始化null
        initNull(bill);
        var sb = new StringBuilder();
        sb.append(time.substring(0,4)).append("-").append(time.substring(4,6));
        //账单月份
        bill.setBillMonth(sb.toString());
        //账单日
        bill.setBillDate(yyyy_MM_dd_PARSER.parse(sb.append("-01").toString()));
        var index = 0;
        //消费信息
        var expenseList = new ArrayList();
        for each(var transMap in transList) {
            index++;
            try {
                //获取分期数据
                var e = getInstanceExpense(transMap, data, index);
                expenseList.add(e);
            } catch (e) {
                logger.error("平安借记卡消费信息异常, taskKey:"+context.get(LUA_TASK_KEY), e);
                statCaughtException(context, e);
            }
        }
        //添加今天的消费情况
        addExpense(count, map, index, data, expenseList);
        bill.setShoppingSheets(expenseList);
        billList.add(bill);
    }
    data.setBills(billList);

}

/**
 * 初始化null值
 */
function initNull(bill){
    bill.setCashLimit(null);
    bill.setCreditLimit(null);
    bill.setInterest(null);
    bill.setLastBalance(null);
    bill.setLastPayment(null);
    bill.setMinPayment(null);
    bill.setNewBalance(null);
    bill.setNewCharges(null);
    initUsdNull(bill);
}

/**
 * 初始化null值，美元相关
 */
function initUsdNull(bill){
    //美元相关
    bill.setUsdCashLimit(null);
    bill.setUsdCreditLimit(null);
    bill.setUsdInterest(null);
    bill.setUsdLastBalance(null);
    bill.setUsdLastPayment(null);
    bill.setUsdMinPayment(null);
    bill.setUsdNewBalance(null);
    bill.setUsdNewCharges(null);
}

/**
 * 当天消费的只能单独查询
 */
function addExpense(count,map,index,data,expenseList){
    //判断是否当月
    if(Integer.parseInt(count)!=1){
        return;
    }
    //格式化日期
    var today = DateFormatUtils.format(Calendar.getInstance(), "yyyyMMdd");
    map.put("startDate", today);
    map.put("endDate", today);

    //获取借记卡信息
    var rspToday = luaFuncs.ajax_post("https://bank.pingan.com.cn/ibp/ibp4pc/work/pcqryTransList.do", map);
    storeDataToFile(context, rspToday,  num+"_bill_shopping_sheets_0.txt")
    logger.info("平安借记卡获取6个月信息，taskKey:{}, 第{}个", context.get(LUA_TASK_KEY), count);

    var rspMapToday = JSON.parse(rspToday);
    var responseBodyToday = rspMapToday.get("responseBody");
    var transListToday = responseBodyToday.get("transList");
    //判断消费记录是否为空
    if(transListToday==null){
        return;
    }
    for each(var transMap in transListToday) {
        index++;
        //获取分期记录
        var e = getInstanceExpense(transMap, data, index);
        expenseList.add(e);
    }
}

/**
 * 获取分期记录
 * @param transMap
 * @param data
 * @param index
 * @returns {Expense}
 */
function getInstanceExpense(transMap,data,index){
    var e = new Expense();
    e.setId(data.getCardId());

    var balance = transMap.get("balance");
    if(balance!=null){
        var d = new BigDecimal(balance);
        if(balance.matches("^\\d+\\.(\\d{3,})$")){
            d = d.setScale(2, RoundingMode.HALF_UP);
        }
        e.setBalance(d);
    }

    var tryeName = transMap.get("typeName");
    var userRemark = transMap.get("userRemark");
    //分期描述
    e.setDescription(tryeName);
    //根据描述判断账单的消费类型
    e.setCategory(judgeBillCategory(tryeName));
    //备注
    e.setRemark(userRemark);
    //卡号
    e.setCardNum(data.getCardNum());
    var date = transMap.get("tranDate");
    //交易时间
    e.setTransDate(yyyy_MM_dd_PARSER.parse(date));
    //记账时间
    e.setPostDate(yyyy_MM_dd_PARSER.parse(date.split(" ")[0]));
    //交易地址
    e.setTransAddr("");
    //交易方式
    e.setTransMethod("");
    //交易通道
    e.setTransChannel("");
    //排序
    e.setOrderIndex(index);
    //钱的类型
    e.setCurrencyType("CNY");

    //获取账单金额
    var tranAmt = transMap.get("tranAmt");
    if(tranAmt!=null){
        var money = new BigDecimal(tranAmt);
        if(tranAmt.matches("^\\d+\\.(\\d{3,})$")){
            money = money.setScale(2, RoundingMode.HALF_UP);
        }

        var ipFlag =  transMap.get("ipFlag");
        if("0".equals(ipFlag)){//如果为0，设置为负数
            e.setAmountMoney(money.negate());
        }else{
            e.setAmountMoney(money);
        }
    }

    //对方银行
    e.setOppositeBank(transMap.get("targetOpenBankName"));
    //对方卡号
    e.setOppositeCardNo(transMap.get("targetAccNo"));
    //对方持卡人姓名
    e.setNameOnOppositeCard(transMap.get("targetAccName"));
    return e;
}

/**
 * 根据描述判断账单的消费类型
 */
function judgeBillCategory(description) {
    if(StringUtils.isBlank(description)){
        return "";
    }
    if (description.contains("消费")) {
        return "CONSUMPTION";
    }else if (description.contains("取现")) {
        return "WITHDRAW";
    }else if (description.contains("还款")||description.contains("转入")) {
        return "PAYMENTS";
    }else if (description.contains("逾期利息")) {
        return "INTEREST";
    }else if (description.contains("延滞金")) {
        return "OVERDUEPAYMENT";
    }else if (description.contains("超额费")) {
        return "OVERDUEFEE";
    }else if (description.contains("分期")) {
        return "INSTALLMENT";
    }else if (description.contains("转账")) {
        return "TRANSFER";
    }else{
        return "SHOPPING";
    }
}

/**
 * 获取月份的月初和月末
 * @param cal 日期
 * @param isDecr 是否月份减少
 * @return
 */
function getStartEnd(cal,isDecr){
    //获取年
    var year = cal.get(Calendar.YEAR);
    //获取月
    var cumonth = cal.get(Calendar.MONTH);
    cumonth=cumonth+1;
    var month = Integer.parseInt(cumonth)
    //月份是否减少
    if(isDecr){
        if(month==1){
            Integer.parseInt(year--);
            month = Integer.parseInt(12);
        }else{
            Integer.parseInt(month--);
        }
    }

    cal.set(Calendar.YEAR, Integer.parseInt(year));
    cal.set(Calendar.MONTH, Integer.parseInt(month-1));
    var maxDate = cal.getActualMaximum(Calendar.DATE);

    var sb = new StringBuilder();
    month = Integer.parseInt(month)
    year = Integer.parseInt(year)
    sb.append(year);
    var m = String.valueOf(month);
    if(m.length==1){
        sb.append("0");
    }
    sb.append(month);
    var yearMonth = sb.toString();

    var map = new HashMap();
    map.put("startDate", yearMonth+"01");
    map.put("endDate", yearMonth+maxDate);
    return map;
}

/**
 * 判断登录状态
 */
function checkLoginStatus(){
    var loginUrl = luaFuncs.get_url();
    logger.info("任务【{}】，平安借记卡, loginUrl:{}", context.get(LUA_TASK_KEY), loginUrl);
    for (var i = 0; i < 8; i++) {
        if(loginUrl.length==0 || loginUrl.contains("returnURL=index%2FindexInfo%2Findex")){
            loginUrl = luaFuncs.get_url();
            logger.info("任务【{}】，平安借记卡, loginUrl:{}", context.get(LUA_TASK_KEY), loginUrl);
            Thread.sleep(2000);
        }else{
            break;
        }
    }
    Thread.sleep(2000);
    //根据id找到错误提示信息
    var otherErrorMsg  = luaFuncs.get_final_error_by_id();
    storeDataToFile(context,otherErrorMsg, "loginresult1.txt");
    if(StringUtils.isBlank(loginUrl) || loginUrl.contains("returnURL=index%2FindexInfo%2Findex")){
        return "登录成功后页面跳转超时";
    }else{
        return otherErrorMsg;
    }
}

/**
 * 根据登录方式返回登录信息
 */
function getLoginText(){
    var loginType = Constants.TASK_LOGIN_TYPE;
    var loginStr = getLoginParams(context)[0];
    return loginStr;
}

var luaFuncs = {
    get: function (url) {
        var map = new HashMap();
        map.put("method", "get");
        map.put("url", url);
        return sendAndReceive(map);
    },
    set_input_by_id:function(id,text){
        var map = new HashMap();
        map.put("method", "set_input_by_id");
        map.put("id", id);
        map.put("text", text);
        return sendAndReceive(map);
    },
    click_by_id_wait_id:function(click_id,wait_id){
        var map = new LinkedHashMap();
        map.put("method", "click_by_id_wait_id");
        map.put("click_id", click_id);
        map.put("wait_id", wait_id);
        return sendAndReceive(map)
    },
    set_input_text_by_id:function (id, text) {
        var map = new LinkedHashMap();
        map.put("method", "set_input_text_by_id");
        map.put("id", id);
        map.put("text", text);
        return sendAndReceive(map);
    },
    show:function () {
        var map = new LinkedHashMap();
        map.put("method", "show");
        return sendAndReceive(map);
    },
    hide:function () {
        var map = new LinkedHashMap();
        map.put("method", "hide");
        return sendAndReceive(map);
    },
    click_pingan_wait:function (id, time) {
        var map = new HashMap();
        map.put("method", "click_pingan_wait");
        map.put("time_out", time);
        map.put("click_id", id);
        return sendAndReceive(map);
    },
    get_url:function () {
        var map = new LinkedHashMap();
        map.put("method", "get_url");
        return sendAndReceive(map);

    },
    get_html_by_id:function (id) {
        var map = new LinkedHashMap();
        map.put("method", "get_html_by_id");
        map.put("id", id);
        var result = sendAndReceive(map);
        if (StringUtils.isBlank(result) || result.equals("get id fail") || result.equals("get element error")) {
            return "";
        }
        return result;
    },
    ajax_post:function (url,postdata) {
        var map = new LinkedHashMap();
        var sb = new StringBuffer();
        for each(var key in postdata.keySet()) {
            sb.append(key + "=" + postdata.get(key) + "&");
        }
        var data = "";
        if (sb.length() > 0) {
            data = sb.substring(0, sb.length() - 1);
        }
        map.put("method", "ajax_post");
        map.put("url", url);
        map.put("data", data);
        return sendAndReceive(map);
    },
    shownotop:function () {
        var map = new LinkedHashMap();
        map.put("method", "shownotop");
        return sendAndReceive(map);
    },
    click_pwd_login_tab:function () {
        var map = new LinkedHashMap();
        map.put("method", "click_pwd_login_tab");
        return sendAndReceive(map);
    },
    get_sms_error_by_id:function () {
        var map = new LinkedHashMap();
        map.put("method", "get_sms_error_by_id");
        return sendAndReceive(map);
    },

    get_final_error_by_id:function () {
        var map = new LinkedHashMap();
        map.put("method", "get_final_error_by_id");
        return sendAndReceive(map);
    }
}